from flask import (Blueprint,
                   views,
                   render_template,
                   request,redirect,
                   session,
                   url_for,
                   g,abort)
from utils.captcha import Captcha
from utils import safeutils
from io import BytesIO
from utils import sendsms,restful
from datetime import datetime
from sqlalchemy import or_

from apps.common.views import handle_time
from .models import FrontUser
from ..models import BannerModel,BoardModel,PostModel,CommentModel,HighlightPostModel
from .forms import SignupForm,SigninForm,AddpostForm,AddCommentForm
from exts import db
from .decorators import login_required
from flask_paginate import get_page_parameter,Pagination
from sqlalchemy.sql import func
import config
bp = Blueprint('front',__name__)

@bp.route('/')
def index():
    board_id =  request.args.get('bd',type=int,default=None)
    banners = BannerModel.query.order_by(BannerModel.priority.desc()).limit(4)
    boards = BoardModel.query.all()
    #获取前台选择排序的st
    sort = request.args.get('st',type=int,default=1)
    page = request.args.get(get_page_parameter(),type=int,default=1)
    start = (page - 1)*config.PER_NUM
    end = start + config.PER_NUM
    posts = None
    total = 0
    query_obj = None
    if sort == 1:
        #按照最新的方式
        query_obj = PostModel.query.order_by(PostModel.create_time.desc())
    elif sort == 2:
        #按照加精的时间倒序排序
        query_obj = db.session.query(PostModel).outerjoin(HighlightPostModel).order_by(HighlightPostModel.create_time.desc(),PostModel.create_time.desc())
    elif sort == 3:
        #点赞排序
        query_obj = PostModel.query.order_by(PostModel.create_time.desc())
    elif sort == 4:
        #按照评论数量倒序排序
        query_obj = db.session.query(PostModel).outerjoin(CommentModel).group_by(PostModel.id).order_by(func.count(CommentModel.id).desc(),PostModel.create_time.desc())

## 先进行过滤，再进行排序
    if board_id:
        post_obj = query_obj.order_by(PostModel.create_time.desc()).filter(PostModel.board_id == board_id)
        posts = post_obj.slice(start,end)
        total = post_obj.count()
    else:
        posts = query_obj.order_by(PostModel.create_time.desc()).slice(start,end)
        total = query_obj.count()
    pagination = Pagination(bs_version=3, page=page, total=total)
    context = {
        'banners':banners,
        'boards':boards,
        'posts':posts,
        'pagination':pagination,
        'current_board':board_id,
        'current_sort':sort
    }
    return render_template('front/front_index.html',**context)

@bp.route('/search/')
def search():
    q = request.args.get('q')
    page = request.form.get(get_page_parameter(),type=int,default=1)
    board_id = request.args.get('bd', type=int, default=None)
    banners = BannerModel.query.order_by(BannerModel.priority.desc()).limit(4)
    boards = BoardModel.query.all()
    # 获取前台选择排序的st
    sort = request.args.get('st', type=int, default=1)
    start = (page - 1) * config.PER_NUM
    end = start + config.PER_NUM
    total = PostModel.query.filter(or_(PostModel.content.contains(q),PostModel.title.contains(q))).count()
    pagination = Pagination(bs_version=3, page=page,total=total)
    posts = PostModel.query.order_by('-create_time').filter(or_(PostModel.content.contains(q),PostModel.title.contains(q))).slice(start,end)
    context = {
        'posts':posts,
        'pagination':pagination,
        'banners':banners,
        'boards':boards
    }
    if posts:
        return render_template('front/front_index.html',**context)
#个人中心页面
@bp.route('/profile/<user_id>')
@login_required
def profile(user_id):
    if not user_id:
        return abort(404)
    user = FrontUser.query.get(user_id)
    if not user:
        return abort(404)
    context = {
        'current_user':user
    }
    return render_template('front/front_profile.html',**context)


#个人中心帖子页面
@bp.route('/profile/posts/',methods=['GET'])
@login_required
def profile_post():
    user_id = request.args.get('user_id')
    if not user_id:
        return abort(404)
    user = FrontUser.query.get(user_id)
    if user:
        context = {
            'current_user':user
        }
        return render_template('front/front_profile_posts.html',**context)
    else:
        return abort(404)


@bp.route('/apost/',methods=["GET","POST"])
@login_required
def apost():
    if request.method == "GET":
        boards = BoardModel.query.all()
        return render_template('front/front_apost.html',boards=boards)
    else:
        form = AddpostForm(request.form)
        if form.validate():
            title = form.title.data
            content = form.content.data
            board_id = form.board_id.data

            board = BoardModel.query.get(board_id)
            if not board:
                return restful.params_error('版块不存在！')
            post = PostModel(title=title,content=content)
            post.board = board
            post.author = g.front_user
            db.session.add(post)
            db.session.commit()
            return restful.success()
        else:
            return restful.params_error(message=form.get_error())


#帖子详情
@bp.route('/pdetail/<post_id>')
def pdetail(post_id):
    post = PostModel.query.filter(PostModel.id == post_id).first()
    comments = CommentModel.query.order_by(CommentModel.create_time.desc()).filter_by(post_id=post_id)
    post.read_count += 1
    db.session.commit()
    context = {
        'post':post,
        'comments':comments
    }
    if not post:
        abort(404)
    return render_template('front/front_pdetail.html',**context)

#发表评论
@bp.route('/acomment/',methods=["POST"])
def addcomment():
    form = AddCommentForm(request.form)
    if form.validate():
        content = form.content.data
        post_id = form.post_id.data
        post = PostModel.query.get(post_id)
        if post:
            comment = CommentModel(content=content)
            comment.post = post
            comment.author = g.front_user
            db.session.add(comment)
            db.session.commit()
            return restful.success()
        else:
            return restful.params_error('没有这篇帖子！')
    else:
        return restful.params_error(form.get_error())


@bp.route('/rcomment/')
def replycomment():
    post_id = request.form.get('post_id')
    content = request.form.get('content')
    comment_id = request.form.get('comment_id')

    comment_model = CommentModel(content=content)

    post_model = PostModel.query.get(post_id)
    comment_model.post = post_model
    comment_model.author = g.front_user

    if comment_id:
        origin_comment = CommentModel.query.get(comment_id)
        comment_model.origin_comment = origin_comment
    db.session.add(comment_model)
    db.session.commit()
    return restful.success()


#注销登录
@bp.route('/logout/')
def logout():
    session.clear()
    return redirect(url_for('front.signin'))

# get方法用来测试短信验证码的发送
# @bp.route('/sms_captcha/')
# def sms_captcha():
#     text = '【253云通讯】您的验证码是8888'
#     phone = '18220568578'
#     result = Send_sms.send_sms(phone,text=text)
#     if result:
#         return 'Success'
#     else:
#         return 'Fail'
class SignupView(views.MethodView):
    def get(self):
        return_to = request.referrer
        # print('此时转过来的网站是：',return_to)
        # print(request.host_url)
        # print(request.url)
        if return_to and return_to != request.url and safeutils.is_safe_url(return_to):
            return render_template('front/front_signup.html',return_to=return_to)
        else:
            return render_template('front/front_signup.html')

    def post(self):
        form = SignupForm(request.form)
        if form.validate():
            telephone = form.telephone.data
            regist_user = FrontUser.query.filter(FrontUser.telephone == telephone).first()
            if regist_user:
                return restful.params_error('该手机号已注册！')
            else:
                username = form.username.data
                password = form.password1.data
                user = FrontUser(telephone=telephone,username=username,password=password)
                db.session.add(user)
                db.session.commit()
                return restful.success()
        else:
            print(form.get_error())
            return restful.params_error()

class SigninView(views.MethodView):
    def get(self):
        return_to = request.referrer
        # print(url_for('front.signup'))
        # print(return_to)
        # print(request.url)
        if return_to and return_to != request.url and return_to  and safeutils.is_safe_url(return_to):
            return render_template('front/front_signin.html', return_to=return_to)
        else:
            return render_template('front/front_signin.html')

    def post(self):
        form = SigninForm(request.form)
        if form.validate():
            telephone = form.telephone.data
            password = form.password.data
            remember = form.remember.data
            user = FrontUser.query.filter_by(telephone=telephone).first()
            if user and user.check_pwd(password):
                #如果登录成功，将用户的信息ID保存到session 中的 Front_user_id当中
                session[config.FRONT_USER_ID] = user.id
                if user.old_login_time:
                    user.last_login_time = user.old_login_time
                user.old_login_time = datetime.now()
                print(user.last_login_time)
                db.session.commit()
                if remember:
                    session.permanent = True
                return restful.success()
            else:
                return restful.params_error(message='手机号或密码错误！')

        else:
            return restful.params_error(message=form.get_error())



bp.add_url_rule('/signup/',view_func=SignupView.as_view('signup'))
bp.add_url_rule('/signin/',view_func=SigninView.as_view('signin'))
